Skip to content

[WIP] Separate SwiftKit into SwiftKitCore and SwiftKitFFM #300

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

madsodgaard
Copy link
Contributor

The goal of this PR is to separate SwiftKit into two modules:

  • SwiftKitCore: A module that supports non-FFM memory management and uses JNI for any downcalls.
  • SwiftKitFFM: A module that uses FFM for allocation of memory and downcalls.

It is still early work in progress. But the vision I have is that SwiftInstance now provides a destroy method that the JNI code can then override to call into the VWT from Swift and deallocate the pointer, while FFM can still use the existing VWT calling.

@ktoso
Copy link
Collaborator

ktoso commented Jul 7, 2025

But the vision I have is that SwiftInstance now provides a destroy method that the JNI code can then override to call into the VWT from Swift and deallocate the pointer, while FFM can still use the existing VWT calling.

I think that's the right call, but let's avoid getting the method via reflection and instead just give the cleanup something to run, rather that reflection trick and it'll be fine 👍

}
// val test by getting(JvmTestSuite::class) {
// useJUnitJupiter("5.10.3")
// }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was this necessary?

@@ -12,7 +12,7 @@
//
//===----------------------------------------------------------------------===//

package org.swift.swiftkit;
package org.swift.swiftkitffm;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
package org.swift.swiftkitffm;
package org.swift.swiftkit.ffm;

I'd do a sub package like this; and everything we do in this module should be contained in this package then

@@ -16,7 +16,7 @@ plugins {
id("build-logic.java-application-conventions")
}

group = "org.swift.swiftkit"
group = "org.swift.swiftkitffm"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
group = "org.swift.swiftkitffm"
group = "org.swift.swiftkit.ffm"

let's do subpackage, that's "typical"

@@ -0,0 +1,21 @@
package org.swift.swiftkitffm;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a heads up to remember the license headers

import java.lang.foreign.MemorySegment;
import java.util.concurrent.ThreadFactory;

public interface AllocatingSwiftArena extends SwiftArena {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice, I think this makes sense; and the factories on the interface as well


try {
// Use reflection to look for the static destroy method on the wrapper.
Method method = clazz.getDeclaredMethod("destroy", long.class);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can pass a Function rather than Class to the constructor and store that; We shouldn't need to resort to reflection here AFAICS.

id("build-logic.java-application-conventions")
}

group = "org.swift.swiftkitcore"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the group for them all is org.swift.swiftkit

and the artif

Suggested change
group = "org.swift.swiftkitcore"
group = "org.swift.swiftkit"

but the artifact id will come from the module name, which will be SwiftKitCore and SwiftKitFFM -> swiftkit-core + swiftkit-ffm

Setting those is done in publishing { publications { maven(MavenPublication) if I read this correctly... Either way -- the group ID remains the same for all those and you don't need to worry about the artifact IDs yet

if (selfType != null && selfPointer != null) {
System.out.println("[debug] Destroy swift value [" + selfType.getSwiftName() + "]: " + selfPointer);
SwiftValueWitnessTable.destroy(selfType, selfPointer);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good


public class SwiftKit {
public class SwiftFFM {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can call this type SwiftRuntime now as it is the runtime entrypoints we call using ffm... No need to call it FFM in the type -- it is in the ffm module (or rather .foreign module)

public static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls");

private static final String STDLIB_MACOS_DYLIB_PATH = "/usr/lib/swift/libswiftCore.dylib";

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice, that's a nice centralization of this logic.

Let's make the class final

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants